// MineGrid.h

#ifndef MINEGRID_H
#define MINEGRID_H

#include "Mine.h"
#include "Size.h"
#include "Point.h"
#include <vector>
//#include <SFML/System.hpp>

/**
* Contains and manages the mines in the game.
*/
class MineGrid
{
public:
	/**
	* Constructor.
	*/
	MineGrid();

	/**
	* Constructor.
	*
	* @param size the new size value.
	*/
	MineGrid( const Size& size );

	/**
	* Destructor.
	*/
	~MineGrid();

	/**
	* Resets the grid and clock.
	*/
	void reset();

	/**
	* Resizes the grid to the given size.
	*
	* @param size the new size of the grid.
	*/
	void resize( const Size& size );

	/**
	* Checks if the player is done with the game
	*
	* @return bool true if the grid is finished.
	*/
	bool isDone() const;

	/**
	* Checks if the mine has been swept.
	*
	* @param p the point to the mine.
	* @return bool if the mine has been swept.
	*/
	bool isSwept( const Point& p ) const;

	/**
	* Sweeps the mine.
	*
	* @param p the point to the mine.
	*/
	void sweepMine( const Point& p );

	/**
	* Checks if the mine has been flagged.
	*
	* @param p the point to the mine.
	* @return bool if the mine has been flagged.
	*/
	bool isFlagged( const Point& p ) const;

	/**
	* Flags the mine.
	*
	* @param p the point to the mine.
	*/
	void flagMine( const Point& p );

	/**
	* Checks wether or not the square is a mine or not.
	*
	* @param p the point to the mine.
	* @return bool if the square is a mine or not.
	*/
	bool isMine( const Point& p ) const;

	/**
	* Returns the number of adjacent mines around
	* the square around the given mine.
	*
	* @param p the point to the mine.
	* @return int the state of the mine.
	*/
	int getAdjacentMines( const Point& p ) const;

	/**
	* Returns the size of the grid.
	*
	* @return Size the grid size.
	*/
	Size getSize() const;

private:
	// The column of mines.
	typedef std::vector<Mine> column;

	// The rows of columns.
	std::vector<column> grid;

	// Keeps track of the time.
	//sf::Clock *clock;

	// Keeps track of the size of the grid.
	Size gridSize;

	/**
	* Increments the number of adjacent in each of the
	* squares around the given point.
	*
	* @param p the center point.
	*/
	void incrementAdjacentSquares( const Point& p );

	/**
	* Returns the number of adjacent flagged mines.
	*
	* @param p the center mine.
	* @return int the number of adjacent flagged mines.
	*/
	int numberOfAdjacentFlaggedMines( const Point& p );

	/**
	* Sweeps the adjacent non flagged mines, if the number
	* of flagged mines are equal or greater than the
	* adjacency number.
	*
	* @param p the center mine.
	*/
	void sweepAdjacentNonFlaggedMines( const Point& p );

	/**
	* Sweeps all of the adjacent non-mine squares.
	*
	* @param p the center mine.
	*/
	void sweepAdjacentNoneMines( const Point& p );

	/**
	* Checks if the point is an "empty/0" square and
	* sweeps the adjacent mines accordingly.
	*
	* @param p position of the center mine to check
	*/
	void checkAdjacentNoneMine( const Point& p );

	/**
	* Checks wether or not the point is a valid position
	* in the grid.
	*
	* @param p the point to validate.
	* @return bool true if the point is valid.
	*/
	bool isValidPoint( const Point& p ) const;
};

#endif // MINEGRID_H
